package com.ylt.producer_consumer;

/*
 * 线程之间的通信问题：生产者和消费者问题！等待唤醒，通知唤醒
 * */
public class SynchronizedPC {
    public static void main(String[] args) {
        Date date = new Date();
        new Thread(() -> {
            for (int i = 0; i < 60; i++) {
                try {
                    date.increment();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }, "A").start();

        new Thread(() -> {
            for (int i = 0; i < 60; i++) {
                try {
                    date.decrement();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }, "B").start();

        new Thread(() -> {
            for (int i = 0; i < 60; i++) {
                try {
                    date.increment();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }, "C").start();

        new Thread(() -> {
            for (int i = 0; i < 60; i++) {
                try {
                    date.decrement();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }, "D").start();
    }
}

//判断等待、业务、通知
class Date {  //资源类
    private int number = 0;

    //+1
    public synchronized void increment() {
        while (number != 0) {
            //等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        //业务
        number++;
        System.out.println(Thread.currentThread().getName() + "=>" + number);
        //通知其他线程
        this.notify();
    }

    //-1
    public synchronized void decrement() {
        while (number == 0) {
            //等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        //业务
        number--;
        System.out.println(Thread.currentThread().getName() + "=>" + number);
        //通知其他线程
        this.notify();
    }
}
